﻿using Carter;
using DDD.Common.Const;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace DDD.Api.Endpoints
{
    public class OAuthEndpoint : ICarterModule
    {
        public async void AddRoutes(IEndpointRouteBuilder app)
        {
            var group = app.MapGroup("api/oauth");
            group.MapGet("token", async ([FromServices] IHttpContextAccessor httpContextAccessor) =>
            {
                var access_token = await httpContextAccessor.HttpContext.GetTokenAsync(AuthenticationConst.OAuth.ACCESS_TOKEN);
                var refresh_token = await httpContextAccessor.HttpContext.GetTokenAsync(AuthenticationConst.OAuth.REFRESH_TOKEN);
                var user = httpContextAccessor.HttpContext.User;

                return new
                {
                    access_token,
                    refresh_token
                };
            }).RequireAuthorization();

            group.MapGet("refresh-token", async (string refreshToken, [FromServices] IHttpClientFactory httpClientFactory, [FromServices] IHttpContextAccessor httpContextAccessor) =>
            {
                if (string.IsNullOrEmpty(refreshToken))
                    return new { message = $"{nameof(refreshToken)}不能为空" };

                using var httpClient = httpClientFactory.CreateClient();
                httpClient.BaseAddress = new Uri("http://47.93.45.55:6001");

                var response = await httpClient.GetAsync($"oauth/RefreshToken?grant_type=refresh_token&refresh_token={refreshToken}");

                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsStringAsync();
                    var tokenDto = JsonConvert.DeserializeObject<OAuthDto>(result);

                    var authenticate = await httpContextAccessor.HttpContext!.AuthenticateAsync(AuthenticationConst.OAuth.DEFAULT);
                    if (authenticate != null)
                    {
                        authenticate.Properties!.UpdateTokenValue(AuthenticationConst.OAuth.ACCESS_TOKEN, tokenDto!.access_token);
                        await httpContextAccessor.HttpContext!.SignInAsync(AuthenticationConst.Cookie.DEFAULT, authenticate.Principal!, authenticate.Properties);
                    }

                    return new { message = tokenDto!.access_token };
                }

                return new { message = "请求异常" };
            });

            group.MapGet("serect-resource", async ([FromServices] IHttpClientFactory httpClientFactory, [FromServices] IHttpContextAccessor httpContextAccessor) =>
            {
                var access_token = await httpContextAccessor.HttpContext!.GetTokenAsync(AuthenticationConst.OAuth.ACCESS_TOKEN);
                if (string.IsNullOrEmpty(access_token))
                    return new { message = "access_token为空，请先试用token接口进行登录" };

                using var httpClient = httpClientFactory.CreateClient();
                httpClient.BaseAddress = new Uri("http://47.93.45.55:6002");

                var response = await httpClient.GetAsync($"resource/serect?authorization={access_token}");
                if (response.IsSuccessStatusCode)
                    return new { message = await response.Content.ReadAsStringAsync() };

                return new { message = response.StatusCode.ToString() };
            });
        }


        record OAuthDto
        {
            public string access_token { get; init; }

            public string token_type { get; init; }

            public DateTime expires_in { get; init; }

        }
    }
}
